#pragma once

// Standard library includes
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#include <memory>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <iomanip>

using namespace std;

// Constants
const string ADMIN_USERNAME = "admin";
const string ADMIN_PASSWORD = "admin123";
const string DATA_C_FILE = "customers.txt";
const string DATA_P_FILE = "products.txt";
const string DATA_PROMO_FILE = "promotions.txt";

// Forward declarations
class PromotionManager;
class Product;
class Order;
class Customer;

// 管理员类
class Admin
{
private:
    string username;
    string password;

public:
    // 提供默认构造函数
    Admin(const string &u = ADMIN_USERNAME, const string &p = ADMIN_PASSWORD)
        : username(u), password(p) {}
    bool login(const string &u, const string &p) const
    {
        return username == u && password == p;
    }
};

// 促销活动基类
class Promotion {
protected:
    string promotionId;
    time_t startTime;
    time_t endTime;
    string description;

public:
    Promotion(const string& id, time_t start, time_t end, const string& desc)
        : promotionId(id), startTime(start), endTime(end), description(desc) {}
    
    virtual ~Promotion() = default;
    
    // 检查促销是否有效
    bool isValid() const {
        time_t now = time(nullptr);
        return now >= startTime && now <= endTime;
    }
    
    // 获取促销标签
    virtual string getPromotionLabel() const = 0;
    
    // 计算促销价格
    virtual double calculatePrice(double originalPrice) const = 0;
    
    // Getters
    string getPromotionId() const { return promotionId; }
    time_t getStartTime() const { return startTime; }
    time_t getEndTime() const { return endTime; }
    string getDescription() const { return description; }
};

// 折扣促销类
class DiscountPromotion : public Promotion {
private:
    double discountRate; // 折扣率，如0.8表示8折

public:
    DiscountPromotion(const string& id, time_t start, time_t end, 
                     const string& desc, double rate)
        : Promotion(id, start, end, desc), discountRate(rate) {}
    
    string getPromotionLabel() const override {
        return to_string(int(discountRate * 10)) + "折";
    }
    
    double calculatePrice(double originalPrice) const override {
        return originalPrice * discountRate;
    }
    
    double getDiscountRate() const { return discountRate; }
};

// 满减促销类
class FullReductionPromotion : public Promotion {
private:
    double threshold;  // 满多少
    double reduction; // 减多少

public:
    FullReductionPromotion(const string& id, time_t start, time_t end,
                          const string& desc, double thres, double red)
        : Promotion(id, start, end, desc), threshold(thres), reduction(red) {}
    
    string getPromotionLabel() const override {
        return "满" + to_string(int(threshold)) + "减" + to_string(int(reduction));
    }
    
    double calculatePrice(double originalPrice) const override {
        if (originalPrice >= threshold) {
            return originalPrice - reduction;
        }
        return originalPrice;
    }
    
    double getThreshold() const { return threshold; }
    double getReduction() const { return reduction; }
};

// 促销管理类
class PromotionManager {
private:
    unordered_map<string, vector<shared_ptr<Promotion>>> productPromotions; // 商品ID -> 促销列表
    vector<shared_ptr<FullReductionPromotion>> globalPromotions; // 全局满减促销

public:
    // 添加商品促销
    void addProductPromotion(const string& productName, shared_ptr<Promotion> promotion) {
        productPromotions[productName].push_back(promotion);
    }
    
    // 添加全局满减促销
    void addGlobalPromotion(shared_ptr<FullReductionPromotion> promotion) {
        globalPromotions.push_back(promotion);
    }
    
    // 获取商品的促销标签
    vector<string> getPromotionLabels(const string& productName) const {
        vector<string> labels;
        auto it = productPromotions.find(productName);
        if (it != productPromotions.end()) {
            for (const auto& promo : it->second) {
                if (promo->isValid()) {
                    labels.push_back(promo->getPromotionLabel());
                }
            }
        }
        return labels;
    }
    
    // 计算商品最终价格（考虑折扣和满减）
    double calculateFinalPrice(const string& productName, double originalPrice, double totalAmount) const {
        double price = originalPrice;
        
        // 应用商品折扣
        auto it = productPromotions.find(productName);
        if (it != productPromotions.end()) {
            for (const auto& promo : it->second) {
                if (promo->isValid() && dynamic_cast<DiscountPromotion*>(promo.get())) {
                    price = promo->calculatePrice(price);
                    break; // 只应用一个折扣
                }
            }
        }
        
        // 应用全局满减
        for (const auto& promo : globalPromotions) {
            if (promo->isValid() && totalAmount >= promo->getThreshold()) {
                return promo->calculatePrice(price);
            }
        }
        
        return price;
    }
    
    // 清理过期促销
    void cleanExpiredPromotions() {
        time_t now = time(nullptr);
        for (auto& pair : productPromotions) {
            auto& promos = pair.second;
            promos.erase(
                remove_if(promos.begin(), promos.end(),
                         [now](const shared_ptr<Promotion>& p) {
                             return p->getEndTime() < now;
                         }),
                promos.end());
        }
        
        globalPromotions.erase(
            remove_if(globalPromotions.begin(), globalPromotions.end(),
                     [now](const shared_ptr<FullReductionPromotion>& p) {
                         return p->getEndTime() < now;
                     }),
            globalPromotions.end());
    }

    // 从文件加载促销信息
    void loadFromFile(const string& filename) {
        ifstream file(filename);
        if (!file) return;

        string line;
        while (getline(file, line)) {
            istringstream iss(line);
            string type, id, startDate, endDate;
            
            if (!(iss >> type >> id >> startDate >> endDate)) continue;
            
            tm startTm = {}, endTm = {};
            sscanf(startDate.c_str(), "%d-%d-%d", &startTm.tm_year, &startTm.tm_mon, &startTm.tm_mday);
            sscanf(endDate.c_str(), "%d-%d-%d", &endTm.tm_year, &endTm.tm_mon, &endTm.tm_mday);
            startTm.tm_year -= 1900;
            startTm.tm_mon -= 1;
            endTm.tm_year -= 1900;
            endTm.tm_mon -= 1;
            
            time_t startTime = mktime(&startTm);
            time_t endTime = mktime(&endTm);

            if (type == "DISCOUNT") {
                string productName;
                double discountRate;
                string description;
                
                if (iss >> productName >> discountRate) {
                    getline(iss, description);
                    if (!description.empty() && description[0] == ' ') {
                        description = description.substr(1);
                    }
                    
                    auto promotion = make_shared<DiscountPromotion>(
                        id, startTime, endTime, description, discountRate);
                    addProductPromotion(productName, promotion);
                }
            }
            else if (type == "FULLREDUCTION") {
                double threshold, reduction;
                string description;
                
                if (iss >> threshold >> reduction) {
                    getline(iss, description);
                    if (!description.empty() && description[0] == ' ') {
                        description = description.substr(1);
                    }
                    
                    auto promotion = make_shared<FullReductionPromotion>(
                        id, startTime, endTime, description, threshold, reduction);
                    addGlobalPromotion(promotion);
                }
            }
        }
    }

    // 保存到文件
    void saveToFile(const string& filename) const {
        ofstream file(filename);
        if (!file) return;
        
        // 保存商品折扣
        for (const auto& pair : productPromotions) {
            for (const auto& promo : pair.second) {
                if (auto discountPromo = dynamic_pointer_cast<DiscountPromotion>(promo)) {
                    file << "DISCOUNT "
                         << promo->getPromotionId() << " "
                         << formatDate(promo->getStartTime()) << " "
                         << formatDate(promo->getEndTime()) << " "
                         << pair.first << " "
                         << discountPromo->getDiscountRate() << " "
                         << promo->getDescription() << "\n";
                }
            }
        }
        
        // 保存满减促销
        for (const auto& promo : globalPromotions) {
            file << "FULLREDUCTION "
                 << promo->getPromotionId() << " "
                 << formatDate(promo->getStartTime()) << " "
                 << formatDate(promo->getEndTime()) << " "
                 << promo->getThreshold() << " "
                 << promo->getReduction() << " "
                 << promo->getDescription() << "\n";
        }
    }

    // 获取全局满减促销列表
    const vector<shared_ptr<FullReductionPromotion>>& getGlobalPromotions() const {
        return globalPromotions;
    }

private:
    // 格式化日期
    string formatDate(time_t t) const {
        tm* tm_info = localtime(&t);
        char buffer[20];
        strftime(buffer, 20, "%Y-%m-%d", tm_info);
        return string(buffer);
    }
};

// 商品类
class Product
{
private:
    string category;
    string name;
    double price;
    string description;
    int stock;

public:
    Product(const string &c = "", const string &n = "", double p = 0.0, const string &d = "", int s = 0)
        : category(c), name(n), price(p), description(d), stock(s) {}
    void increaseStock(int amount); // 库存同步
    // get-set方法
    string getName() const
    {
        return name;
    }
    double getPrice() const
    {
        return price;
    }
    int getStock() const
    {
        return stock;
    }
    string getCategory() const
    {
        return category;
    }
    string getDescription() const
    {
        return description;
    }
    void setName(const string &n)
    {
        name = n;
    }
    void setPrice(double p)
    {
        price = p;
    }
    void setStock(int s)
    {
        stock = s;
    }
    void setCategory(const string &c)
    {
        category = c;
    }
    void setDescription(const string &d)
    {
        description = d;
    }
    void decreaseStock(int quantity)
    {
        // 验证输入的数量是否为非负数
        if (quantity < 0)
        {
            cerr << "错误：输入的数量不能为负数。" << endl;
            throw invalid_argument("输入的数量必须是非负数");
        }
        // 检查库存是否充足
        if (stock < quantity)
        {
            cerr << "错误：库存不足，当前库存: " << stock << ", 请求数量: " << quantity << endl;
            throw runtime_error("库存不足，无法减少指定数量");
        }

        if (stock >= quantity)
        {
            stock -= quantity;
            cout << "成功减少，当前库存为->" << stock << endl;
        }
    }

    // 获取促销价格
    double getPromotionalPrice(const PromotionManager& promotionManager, double totalAmount) const {
        return promotionManager.calculateFinalPrice(name, price, totalAmount);
    }
    
    // 获取促销标签
    vector<string> getPromotionLabels(const PromotionManager& promotionManager) const {
        return promotionManager.getPromotionLabels(name);
    }
};

// 购物车类
class ShoppingCart
{
private:
    unordered_map<string, int> items;                         // 商品名称 -> 购买数量
    unordered_map<string, const Product *> productReferences; // 商品名称 -> 商品指针

public:
    void addProduct(const Product &product, int quantity);           // 添加商品
    void removeProduct(const string &productName);                   // 删除商品
    void modifyQuantity(const string &productName, int newQuantity); // 修改数量
    void displayCart(const PromotionManager& promotionManager) const;  // 显示商品
    int getTotalQuantity() const;                                    // 获取总个数
    double getTotalPrice(const PromotionManager& promotionManager) const;  // 获取总价格（含促销）
    void clearCart();                                                // 清空购物车

    // 判断购物车是否为空
    bool isEmpty() const;
    // 获取购物车中的商品及数量
    const unordered_map<string, int> &getItems() const;
    // 获取商品引用
    const unordered_map<string, const Product *> &getProductReferences() const {
        return productReferences;
    }
};

// 顾客类
class Customer
{
private:
    string username;
    string password;
    string name;
    ShoppingCart cart;

public:
    Customer(const string &u = "", const string &p = "",
             const string &n = "userx")
        : username(u), password(p), name(n) {}
    bool changePassword(const string &oldPwd, const string &newPwd)
    {
        if (password == oldPwd)
        {
            password = newPwd;
            return true;
        }
        return false;
    }
    string getUsername() const
    {
        return username;
    }
    string getPassword() const
    {
        return password;
    }
    string getName() const
    {
        return name;
    }
    ShoppingCart &getCart()
    {
        return cart;
    }
};

// 订单类
class Order
{
private:
    string orderId;                   // 订单编号
    time_t createTime;                // 订单创建时间
    string status;                    // 订单状态：待发货、已发货、已签收
    unordered_map<string, int> items; // 商品名称 -> 购买数量
    double totalPrice;                // 订单总价
    string address;                   // 收货地址
    string customerUsername;          // 顾客用户名

public:
    Order(const string &id, const string &username,
          const ShoppingCart &cart,
          const PromotionManager &promotionManager,
          const string &addr);

    // Getters
    string getOrderId() const { return orderId; }
    time_t getCreateTime() const { return createTime; }
    string getStatus() const { return status; }
    unordered_map<string, int> getItems() const { return items; }
    double getTotalPrice() const { return totalPrice; }
    string getAddress() const { return address; }
    string getCustomerUsername() const { return customerUsername; }

    // 修改订单（仅限待发货状态）
    bool updateAddress(const string &newAddress);
    bool cancelOrder(unordered_map<string, Product> &products);

    // 订单状态转换
    bool setStatus(const string &newStatus);
    void displayOrderDetails() const;
};

// 订单列表类
class OrderList
{
private:
    vector<Order> orders;   // 订单集合
    static int nextOrderId; // 下一个订单编号
    const PromotionManager& promotionManager; // Add reference to PromotionManager

public:
    OrderList(const PromotionManager& pm) : promotionManager(pm) {}

    // 修改createOrder签名
    string createOrder(Customer& customer,
                      const unordered_map<string, int>& cartItems,
                      unordered_map<string, Product>& products,
                      const string& address);

    // 查询订单
    vector<Order> getCustomerOrders(const string &username) const;
    Order *findOrderById(const string &orderId);

    // 订单状态管理（自动/手动）
    void updateOrderStatuses(); // 自动更新状态
    bool manuallyUpdateStatus(const string &orderId, const string &newStatus);

    // 显示订单
    void displayCustomerOrders(const string &username) const;

    vector<Order> &getOrders();

    bool removeOrder(const string &orderId); // 添加删除订单的方法
};

// 系统管理类
class System
{
private:
    Admin admin;
    // 使用unordered_map管理顾客和商品
    unordered_map<string, Customer> customers;
    unordered_map<string, Product> products;
    PromotionManager promotionManager;
    OrderList orderList;  // Will be initialized with promotionManager

    void loadCustomers(); // 从文件中读取顾客信息
    void saveCustomers(); // 将存储在 customers 哈希表中的顾客信息保存到customers.txt 的文本文件中
    void loadProducts();
    void saveProducts();
    void loadPromotions();  // 新增：加载促销数据
    void savePromotions();  // 新增：保存促销数据

    // 添加促销管理相关方法
    void managePromotions();
    void addPromotion();
    void viewPromotions() const;
    void removeExpiredPromotions();

    string formatTime(time_t t) const; // 添加格式化时间的辅助函数声明

public:
    System()
        : admin(ADMIN_USERNAME, ADMIN_PASSWORD), 
          orderList(promotionManager)  // Initialize with promotionManager
    {
        loadCustomers();
        loadProducts();
        loadPromotions();  // 新增：加载促销数据
    }
    
    ~System() {
        saveCustomers();
        saveProducts();
        savePromotions();  // 新增：保存促销数据
    }
    void run();

private:
    void adminLogin();
    void adminMenu();

    void customerMenu(Customer &customer);
    void customerLogin();
    void customerRegister();

    void manageProducts();
    void displayProducts() const;
    void addProduct();
    void modifyProduct();
    void deleteProduct();

    void searchProducts();
    void fuzzySearchProducts(const string &keyword);
    void purchaseProduct(Customer &customer);

    // 第三次添加
    void addToCart(Customer &customer);
    void removeFromCart(Customer &customer);
    void modifyCart(Customer &customer);
    void viewCart(Customer &customer);

    // 第四次添加:新增购物流程相关方法
    void purchaseFromProductList(Customer &customer);
    void purchaseFromCart(Customer &customer);
    void viewOrders(Customer &customer);
    void manageOrders(); // 管理员订单管理
    void modifyOrder(Customer &customer);
    void deleteOrder(Customer &customer);

    void mainMenu();
};
